<?php

namespace yphp;
/**
 * Class Route
 * @package yphp
 * 路由类
 */
class Route extends Instance
{
    static $RouteArr = [];

    // 构造方法
    function construct()
    {
        # 引入路由
        $this->load();
        // 验证码初始化
        Route::any('/captcha',function() {
            $obj = \yphp\Captcha::imgCode();
            header('Content-Type:image/png');
            \yphp\Session::set('code', $obj->str);
            exit($obj->img);
        });
        return self::single();
    }

    // 路由 替换 @ 去除 /
    static function routeline($path)
    {
        $path = '@' . str_replace(ROUTELINE, '@', trim($path, '/'));
        return $path === '@' ? '' : $path;
    }

    // 查找是否定义了路由
    function findRoute($path)
    {
        return self::find($path, Request::instance()->method()) ?: self::find($path, 'ANY');
    }

    // 查找方法
    static function find($path, $method)
    {
        $state = false;
        if (key_exists($method, self::$RouteArr)) {
            foreach (self::$RouteArr[$method] as $k => $v) {
                $hasParam = key_exists('where', $v);
                $res = $hasParam ? preg_match($preg = "/^" . (key_exists('preg', $v) ? $v['preg'] : self::parse($method, $k)) . "$/", $path) : $k === $path;
                if (!$res) continue;
                $args = [];
                $method === 'POST' && key_exists('input', $v) && self::input($v['input']);
                if ($hasParam) {
                    preg_match_all($preg, $path, $matches);                    for ($i = 1, $c = count($matches); $i < $c; $i++) {
                        $args[] = $matches[$i][0] ? ltrim($matches[$i][0], '@') : '{@}';
                    }
                }
                $state = ['oper' => $v['oper'], 'args' => $args, 'cache' => key_exists('cache', $v) ? $v['cache'] : Config::web('route_cache_time'), 'path' => $k];

                break;
            }
        }
        return $state;
    }

    // 验证input参数
    static function input($args)
    {
        foreach ($args as $k => $v) {
            is_array($v) || $v = [$v, null];
            list($preg, $msg) = $v;
            $res = preg_match('/^' . $preg . '$/', Request::instance()->post($k));
            if ($res) continue;
            throw new \Exception($msg);
        }
        return true;
    }

    // 路由加载
    private function load()
    {
        $route = Config::route();
        $host = Request::instance()->host();
        $path = key_exists($host, $route) ? $route[$host] : 'route';
        Yphp::loadfile(ROUTE . $path . '.php');
    }

    // 正则解析
    static function parse($method, $path)
    {
        $url = str_replace('/', '\\/', $path);
        foreach (self::$RouteArr[$method][$path]['where'] as $k => $preg) {
            $url = str_replace(['{' . $k . '}', '@{' . $k . '?}'], ['(' . $preg . ')', '(@' . $preg . ')?'], $url);
        }
        return self::$RouteArr[$method][$path]['preg'] = $url;
    }

    // get请求
    static function get($url, $oper)
    {
        return self::confirm(['get'], $url, $oper);
    }

    // post请求
    static function post($url, $oper)
    {

        return self::confirm(['post'], $url, $oper);
    }

    // any请求
    static function any($url, $oper)
    {

        return self::confirm(['any'], $url, $oper);
    }

    // match请求
    static function match($method, $url, $oper)
    {

        return self::confirm($method, $url, $oper);
    }

    // 处理
    static function confirm($method, $url, $oper)
    {
        $url = self::routeline($url);
        foreach ($method as $k => $m) {
            $method[$k] = $m = strtoupper($m);
            key_exists($m, self::$RouteArr) || self::$RouteArr[$m] = [];
            self::$RouteArr[$m][$url] = ['oper' => $oper];
        }
        return Tap::instance($method, $url);
    }

}